package com.lmx.web.controller;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.lmx.common.constants.ICommonConstants;
import com.lmx.common.util.CommonUtil;
import com.lmx.common.util.ImgUtil;
import com.lmx.common.util.URLUtil;
import com.lmx.persistence.service.ImportExcelService;
import com.lmx.persistence.service.TaskService;
import com.lmx.repoDomain.exception.BusinessException;

/*-
 * 文件上传处理
 *
 */

@Controller
public class FileUploadController {
	private static Log logger = LogFactory.getLog(FileUploadController.class);
	// private String rootPath = "d:/temp/upfile";

	@Autowired
	ImportExcelService importExcelService;

	@Autowired
	TaskService taskService;

	@Autowired
	HttpServletResponse response;

	@Autowired
	HttpServletRequest request;

	@RequestMapping(method = RequestMethod.GET, value = "/upload-list")
	@ResponseBody
	public String provideUploadInfo(Model model) {
		File rootFolder = new File(URLUtil.getInstance().getRootDir());
		List<String> fileNames = Arrays.stream(rootFolder.listFiles()).map(f -> f.getName())
				.collect(Collectors.toList());

		model.addAttribute(
				"files",
				Arrays.stream(rootFolder.listFiles())
						.sorted(Comparator.comparingLong(f -> -1 * f.lastModified()))
						.map(f -> f.getName()).collect(Collectors.toList()));

		return "uploadForm";
	}

	@RequestMapping(method = RequestMethod.POST, value = "/upload")
	@ResponseBody
	public String handleFileUpload(@RequestParam("name") String name,
			@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes,
			@RequestParam("Content-Type") String contentType,
			@RequestParam("businessType") String businessType) {
		logger.debug("进入上传方法。");
		Map<String, Object> msgMap = new HashMap<String, Object>();
		String json = null; // 返回json串

		if (name.contains("/")) {
			msgMap.put("flag", "1");
			json = CommonUtil.mapToJsonString(msgMap);
			return json;
		}
		name = CommonUtil.getCurrTimes() + "_" + name; // 修改上传文件名称防止重复
		String relativePath = URLUtil.getInstance().getRelativePath(name);
		String savePath = URLUtil.getInstance().getFullPath(contentType, businessType, name);
		logger.debug("contentType : " + contentType);
		logger.debug("businessType : " + businessType);
		logger.debug("savePath：" + savePath);
		if (!file.isEmpty()) {
			try {
				logger.debug("文件 " + name + " 开始上传");
				File newFile = new File(savePath);
				if (!newFile.getParentFile().exists()) {
					newFile.getParentFile().mkdirs();
				}
				BufferedOutputStream stream = new BufferedOutputStream(
						new FileOutputStream(newFile));
				FileCopyUtils.copy(file.getInputStream(), stream);
				stream.close();
				name = this.transNameToSmall(name);
				savePath = URLUtil.getInstance().getFullPath(contentType, businessType, name);
				// 只有头像的时候生成缩略图
				if (contentType.startsWith("image") && businessType.equals("headImg")) {
					File smallFile = this.convert(file);
					ImgUtil.zoomImgRefWidth(smallFile, ICommonConstants.THUMBNAIL_WIDTH, savePath);
				}
				msgMap.put("relativePath", relativePath);
				msgMap.put("flag", "0");

			} catch (Exception e) {
				e.printStackTrace();
				msgMap.put("flag", "1");
				logger.debug("上传 " + name + " 失败!");
			}
		} else {
			msgMap.put("flag", "1");
			logger.debug("文件 " + name + " 为空，上传失败!");
		}
		json = CommonUtil.mapToJsonString(msgMap);
		return json;
	}

	@RequestMapping(method = RequestMethod.POST, value = "/excelUpload")
	@ResponseBody
	public String excelFileUpload(@RequestParam("file") MultipartFile file,
			@RequestParam("fileName") String fileName, @RequestParam("taskID") String taskID) {
		logger.debug("进入导入excel方法。");
		Map<String, Object> msgMap = new HashMap<String, Object>();
		String json = null; // 返回json串

		// 验证fileName
		if (fileName.contains("/")) {
			msgMap.put("flag", "2");
			msgMap.put("message", "参数错误");
			json = CommonUtil.mapToJsonString(msgMap);
			return json;
		}

		// 验证taskID
		if (taskID.isEmpty()) {
			msgMap.put("flag", "2");
			msgMap.put("message", "参数错误");
			json = CommonUtil.mapToJsonString(msgMap);
			return json;
		}

		// 验证file
		logger.debug("验证excelFile。。。。");
		if (file != null && !file.isEmpty()) {
			logger.debug("验证excelFile通过。。。。");
			InputStream inputStream = null;
			try {
				inputStream = file.getInputStream();
				// 获取任务详情
				/*
				 * Map<String ,Object> taskMap =
				 * taskService.getTask(Long.parseLong(taskID)); //huibati String
				 * taskCode = (String) taskMap.get("taskCode"); if(taskCode !=
				 * null && !taskCode.isEmpty() &&
				 * taskCode.equals("Mobile_service_task")){ msgMap =
				 * importExcelService.getMobileServiceFromExcel(inputStream,
				 * Long.parseLong(taskID)); }else{ msgMap =
				 * importExcelService.getDataFromExcel(inputStream,
				 * Long.parseLong(taskID)); }
				 */

			} catch (IOException e) {
				msgMap.put("flag", "3");
				msgMap.put("message", "系统错误");
			}
		} else {
			msgMap.put("flag", "2");
			msgMap.put("message", "参数错误");
			// logger.debug("文件 " + fileName + " 为空，导入失败!");
		}
		json = CommonUtil.mapToJsonString(msgMap);
		return json;
	}

	/**
	 * @param filePath
	 *            //文件完整路径(包括文件名和扩展名)
	 * @param fileName
	 *            //下载后看到的文件名
	 * @return 文件名
	 * @throws IOException
	 */
	@RequestMapping(method = RequestMethod.GET, value = "/backStand/filedownload")
	public void download(String filePath, String fileName) throws IOException {
		if (!"".equals(filePath)) {
			filePath = new String(filePath.getBytes("ISO-8859-1"), "UTF-8");
			String path = URLUtil.getInstance().getRootDir()
					+ URLUtil.getInstance().getBusinessTypeDir("zipPackage")
					+ URLUtil.getInstance().getBusinessTypeDir("phoneNumAuth") + filePath;
			File file = new File(path);// 构造要下载的文件
			if (file.exists()) {
				InputStream ins = new FileInputStream(path);// 构造一个读取文件的IO流对象
				BufferedInputStream bins = new BufferedInputStream(ins);// 放到缓冲流里面
				OutputStream outs = response.getOutputStream();// 获取文件输出IO流
				BufferedOutputStream bouts = new BufferedOutputStream(outs);
				response.setContentType("application/x-download");// 设置response内容的类型
				response.setHeader("Content-disposition",
						"attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));// 设置头部信息
				int bytesRead = 0;
				byte[] buffer = new byte[8192];
				// 开始向网络传输文件流
				while ((bytesRead = bins.read(buffer, 0, 8192)) != -1) {
					bouts.write(buffer, 0, bytesRead);
				}
				bouts.flush();// 这里一定要调用flush()方法
				ins.close();
				bins.close();
				outs.close();
				bouts.close();
			} else {
				System.out.println("下载的文件不存在");
			}
		} else {
			System.out.println("下载文件时参数错误");
		}
	}

	/**
	 * 生成缩略图的文件名
	 *
	 * @author ytche
	 * @param name
	 * @return
	 * @date 2017年5月17日 下午4:35:50
	 */
	private String transNameToSmall(String name) {
		String[] namePart = name.split("\\.");
		if (namePart.length == 2) {
			name = namePart[0] + "_small" + "." + namePart[1];
		} else {
			throw new BusinessException("", ICommonConstants.UPLOAD_ERROR.NAME_MUL_DOT.label(),
					"文件名异常");
		}
		return name;
	}

	/**
	 * 将MultipartFile转为File
	 *
	 * @author ytche
	 * @param file
	 * @return
	 * @date 2017年5月17日 下午4:37:22
	 */
	private File convert(MultipartFile file) {
		File convFile = new File(file.getOriginalFilename());
		try {
			convFile.createNewFile();
			FileOutputStream fos = new FileOutputStream(convFile);
			fos.write(file.getBytes());
			fos.close();
		} catch (IOException e) {
			logger.error("MultipartFile to file error", e);
		}
		return convFile;
	}
}
